package com.zb.utils;

import cn.dev33.satoken.stp.SaTokenInfo;
import com.zb.constant.UserConstant;
import com.zb.entity.AccounLoginInfo;
import com.zb.entity.AccountLoginToken;
import com.zb.enums.TokenType;
import com.zb.exception.VendorIdentifierException;
import com.zb.redis.RedisLoginTokenUtil;
import com.zb.redis.RedisUserLoginTokenUtil;
import com.zb.secure.BCryptUtil;
import com.zb.stp.StpUserUtil;
import com.zb.yaml.EnDeSecret;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;

/**
 * @Author WEN
 * @Date 2023/11/1 0001
 **/
public class TokenUserUtil {
    /**
     * 从请求头中获取登录token
     * @param request
     * @return
     */
    public static String getToken(HttpServletRequest request) {
        return request.getHeader(TokenType.USER_ACCESS_TOKEN.getType());
    }

    /**
     * 从token中获取账号ID
     * @param request
     * @return
     */
    public static Long getAccountIdByToken(HttpServletRequest request) {
        AccounLoginInfo logintInfo = RedisUserLoginTokenUtil.getAccountLoginInfoByAccessToken(getToken(request));
        if (null == logintInfo) {
            return 0L;
        }
        return logintInfo.getId();
    }

    /**
     * 从token中获取账号ID
     * @param accessToken
     * @return
     */
    public static Long getAccountIdByToken(String accessToken) {
        return getAccountLoginInfo(accessToken).getId();
    }

    /**
     * 从token中获取商家ID
     * @param request
     * @return
     */
    public static Long getcustAccIdByToken(HttpServletRequest request) throws VendorIdentifierException {
        AccounLoginInfo loginInfo = getAccountLoginInfo(request);
        if (null == loginInfo) {
            return getCustAccIdByMobildUserCustCode(request);
        }
        return loginInfo.getCustAccId();
    }

    /**
     * 从token中获取商家Logo存储编码
     * @param request
     * @return
     */
    public static String getCustAccLogoCode(HttpServletRequest request) {
        return getAccountLoginInfo(request).getCustAccLogoCode();
    }

    /**
     * 从token中获取商家附件存储编码
     * @param request
     * @return
     */
    public static String getCustAccAnnexCode(HttpServletRequest request) {
        return getAccountLoginInfo(request).getCustAccAnnexCode();
    }

    /**
     * 从token中获取商家附件存储编码
     * @param request
     * @return
     */
    public static String getCustAccVideoCode(HttpServletRequest request) {
        return getAccountLoginInfo(request).getCustAccVideoCode();
    }

    /**
     * 从token中获取登录账号对象
     * @param request
     * @return
     */
    public static AccounLoginInfo getAccountLoginInfo(HttpServletRequest request) {
        return RedisUserLoginTokenUtil.getAccountLoginInfoByAccessToken(getToken(request));
    }

    /**
     * 从token中获取登录账号对象
     * @param accessToken
     * @return
     */
    public static AccounLoginInfo getAccountLoginInfo(String accessToken) {
        return RedisUserLoginTokenUtil.getAccountLoginInfoByAccessToken(accessToken);
    }

    /**
     * 从请求头中解析报单移动端的商家密钥串
     * @param request
     * @return
     */
    public static Long getCustAccIdByMobildUserCustCode(HttpServletRequest request) throws VendorIdentifierException {
        String custCode = request.getHeader(UserConstant.CUST_CODE);
        if (StringUtils.isBlank(custCode)) {
            throw new VendorIdentifierException("商家认证标识错误，无法识别商家认证标识："+ custCode);
        }
        String custAccIdStr = BCryptUtil.aesDecry(EnDeSecret.aesKey(), custCode);
        if (StringUtils.isBlank(custAccIdStr)) {
            throw new VendorIdentifierException("商家认证标识错误，商家认证标识解析失败：" + custCode);
        }
        long custAccId = Long.parseLong(custAccIdStr);
        return custAccId;
    }

    /**
     * token封装并返回
     * @param admInfo
     * @return
     */
    public static AccountLoginToken getLoginToken(AccounLoginInfo admInfo) {
        // 获取token信息
        SaTokenInfo saToken = StpUserUtil.getTokenInfo();
        // token封装
        AccountLoginToken loginToken = new AccountLoginToken(
                saToken.getTokenName(),
                saToken.getTokenValue(),
                RedisLoginTokenUtil.generatorRefreshToken(),
                saToken.getTokenTimeout()
        );
        RedisUserLoginTokenUtil.setAccountLoginInfoByAccessToken(saToken.getTokenValue(), admInfo);
        RedisUserLoginTokenUtil.setRefreshTokenByAccessToken(loginToken.getTokenValue(), loginToken.getRefreshToken(), admInfo.isRememberMe());
        RedisUserLoginTokenUtil.setAccessTokenByRefreshToken(loginToken.getRefreshToken(), loginToken.getTokenValue(), admInfo.isRememberMe());
        return loginToken;
    }
}
